import { computed, ref } from 'vue'
import type { RandomTestingStore } from '.'
import type { CodeNullable, TypeNullable } from '@/hooks/Classification/types'
import { ClassificationType } from '@/models/Classification/Classification'
import {
  RandomTestingConstants,
  TestTypeKey,
  TestTypeLabel,
  getTestTypeKeyByStr,
} from '../constants/RandomTesting'
import { useRoute } from 'vue-router'
import { useClassificationData } from '@/hooks/Classification/useClassificationData'
import { useClassificationInfo } from '@/hooks/Classification/useClassificationInfo'

export class ClassificationStore {
  constructor(rootStore: RandomTestingStore) {
    this.rootStore = rootStore
    const classificationData = useClassificationData()
    this.loading = classificationData.loading
    this.list = classificationData.list
    this.tree = classificationData.tree
    this.initClassificationData = classificationData.initData
    const classificationInfo = useClassificationInfo({
      code: this.code,
      type: this.type,
      list: this.list,
    })
    this.name = classificationInfo.name
    this.classification = classificationInfo.classification
    this.secondaryClassification = classificationInfo.secondaryClassification
  }

  init = async () => {
    this.initCodeAndType()
    return await this.initClassificationData()
  }

  rootStore

  /**
   * 当前题库级别
   */
  type = ref<TypeNullable>()
  /**
   * 设置当前题库级别
   */
  setType(type: any): boolean {
    if (
      type === ClassificationType.classification ||
      type === ClassificationType.secondaryClassification
    ) {
      this.type.value = type
      localStorage.setItem(RandomTestingConstants.localStorageId.ClassificationType, type)
      return true
    }
    if (type === '') {
      this.type.value = null
      localStorage.setItem(RandomTestingConstants.localStorageId.ClassificationType, type)
      return true
    }
    return false
  }

  /**
   * 当前题库标识
   */
  code = ref<CodeNullable>()
  /**
   * 设置当前题库标识
   */
  setCode(code: any): boolean {
    if (typeof code === 'string' && code) {
      this.code.value = code
      localStorage.setItem(RandomTestingConstants.localStorageId.ClassificationCode, code)
      return true
    }
    if (code === '') {
      this.code.value = null
      localStorage.setItem(RandomTestingConstants.localStorageId.ClassificationCode, code)
      return true
    }
    return false
  }

  testType = ref<TestTypeKey>(TestTypeKey.NotDone)

  testTypeStr = computed(() => {
    const { testType } = this
    return TestTypeLabel[testType.value]
  })

  initTestType = () => {
    const testType = getTestTypeKeyByStr(
      localStorage.getItem(RandomTestingConstants.localStorageId.TestType),
    )
    if (!testType) return
    this.testType.value = testType
  }

  setTestType = (testType: TestTypeKey) => {
    this.testType.value = testType
    localStorage.setItem(RandomTestingConstants.localStorageId.TestType, `${testType}`)
  }

  /**
   * 初始化级别和标识
   *
   * 先从路由初始化，失败之后再尝试从本地存储中初始化
   */
  initCodeAndType(): boolean {
    this.initTestType()
    return this.initCodeAndTypeByRouter() || this.initCodeAndTypeByLocalStorage()
  }

  /**
   * 根据路由初始化级别和标识
   */
  initCodeAndTypeByRouter(): boolean {
    const route = useRoute()
    const { code, type } = route.query
    if (!type || !code) return false
    if (!this.setType(type)) return false
    return this.setCode(code)
  }

  /**
   * 根据本地存储初始化级别和标识
   */
  initCodeAndTypeByLocalStorage(): boolean {
    const type = localStorage.getItem(RandomTestingConstants.localStorageId.ClassificationType)
    const code = localStorage.getItem(RandomTestingConstants.localStorageId.ClassificationCode)
    if (!this.setType(type)) return false
    return this.setCode(code)
  }

  /**
   * 加载所有题库分类数据Loading
   */
  loading
  /**
   * 所有题库分类数组
   */
  list
  /**
   * 所有题库分类树
   */
  tree
  /**
   * 初始化所有分类的方法
   */
  initClassificationData

  /**
   * 当前的题库分类名称
   */
  name
  /**
   * 当前的一级题库分类
   */
  classification
  /**
   * 当前的二级题库分类
   */
  secondaryClassification

  classificationCode = computed(() => {
    const { classification } = this
    return classification.value?.code
  })

  secondaryClassificationCode = computed(() => {
    const { secondaryClassification } = this
    return secondaryClassification.value?.code
  })
}
